<?php
namespace app\common\server;


use XCrawler\Utils;
use GuzzleHttp\Client;
use GuzzleHttp\Cookie\CookieJar;

class Weixinpublic
{

    private $_apis = [
        "host"          => "https://mp.weixin.qq.com",
        "login"         => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin",
        "qrcode"        => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=getqrcode&param=4300&rd=578",
        "loginqrcode"   => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1",
        "loginask"      => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1&random=",
        "loginauth"     => "https://mp.weixin.qq.com/cgi-bin/loginauth?action=ask&token=&lang=zh_CN&f=json&ajax=1",
        "bizlogin"      => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login&lang=zh_CN",
        "searchbiz"      => "https://mp.weixin.qq.com/cgi-bin/searchbiz?action=search_biz&lang=zh_CN&f=json&ajax=1&"
    ];

    private $_redirect_url  = '';

    private $_key           = '';

    private $jar  = '';



    private $_username  = '';

    private $_password  = '';

    private function _getCookieFile(){
        return  RUNTIME_PATH.'weixin_public/'."cookie_{$this->_key}.text";
    }

    private function _getSavePath(){
        return  RUNTIME_PATH.'weixin_public/'.'qrcode_'.$this->_key.'.png';
    }

    private function _log($msg){
        var_dump( "[".date("Y-m-d H:i:s",time())."] ========:".$msg."\n");
    }

    private function getToken(){
        return redis()->get($this->_key.'_token');
    }

    private function setToken($token){
        redis()->set($this->_key.'_token',$token);
        redis()->expire($this->_key.'_token', 86399);
    }


    public function __construct($options){

         if(!isset($options["key"])){
             die("Key is Null!");
         }
         $this->_key     =   $options["key"];


         $this->_username = $options['account'];

         $this->_password = $options['password'];
    }



    public function _init(){
        $token = $this->getToken();
        if($token){
            echo "HAS Token !\n";
            trace(date('Y-m-d H:i:s').'HAS Token !','info');
        }else{
            $param=[];

            $this->fetch('host',$param);

            echo "start login!!\n";

            trace(date('Y-m-d H:i:s').'登陆:start login!!','info');
            $token = $this->start_login();
        }

        return $token;
    }



    //开始扫码验证
    private function start_login(){
        $_res        = $this->_login();


        if ($_res['base_resp']['ret'] !== 0) {
            echo $_res['base_resp']['err_msg']."\n";
            trace(date('Y-m-d H:i:s').'错误信息'.$_res['base_resp']['err_msg'],'info');
            exit;
        }else{
            $this->_redirect_url = "https://mp.weixin.qq.com".$_res["redirect_url"];//跳转路径
        }

        //保存二维码
        $this->_saveQRcode();
        $_ask_api        =   'loginask';
        $_input["refer"] =   $this->_redirect_url;
        $_index          =   1;


        while(true){
            if($_index>60){
                break;
            }
            $_res        =   $this->fetch($_ask_api,$_input);

            $_res = \GuzzleHttp\json_decode($_res->getBody()->getContents(),true);

            trace(date('Y-m-d H:i:s').'二维码回问信息'.json_encode($_res),'info');

            if(isset($_res["status"])){
                $_status     =   $_res["status"];

                if($_status==1){
                    if($_res["user_category"]==1){
                        $_ask_api = "loginauth";
                    }else{
                        echo "Login success";
                        $this->_log("Login success");
                        break;
                    }
                }else if($_status==4){
                    echo "已经扫码\n";
                    trace(date('Y-m-d H:i:s').'已经扫码','info');
                }else if($_status==2){
                    echo "管理员拒绝\n";
                    trace(date('Y-m-d H:i:s').'管理员拒绝','info');
                    break;
                }else if($_status==3){
                    echo "登录超时\n";
                    trace(date('Y-m-d H:i:s').'登录超时','info');
                    break;
                }
            }else{
                if($_ask_api== "loginask"){
                    echo "...";
                    trace(date('Y-m-d H:i:s').'...','info');
                }else{
                    echo "等待确认\n";
                    trace(date('Y-m-d H:i:s').'等待确认','info');
                }
            }
            
            sleep(2);
            $_index++;
        }

        /*if($_index>=60){
            $this->_log("U亲，超时了");
            return;
        }*/

        echo "开始验证\n";
        trace(date('Y-m-d H:i:s').'开始验证','info');

        $_input["post"]      = ["lang"=>"zh_CN","f"=>"json","ajax"=>1,"random"=>$this->getWxRandomNum(),"token"=>""];
        $_input["refer"]     = $this->_apis["host"];
        $_res                = $this->fetch('bizlogin',$_input);
        $_res = \GuzzleHttp\json_decode($_res->getBody()->getContents(),true);

        trace(date('Y-m-d H:i:s').json_encode($_res),'info');
//        $this->_log(print_r($_res,true));

        if($_res["base_resp"]["ret"]!=0){
            trace(date('Y-m-d H:i:s').$_res["base_resp"]["err_msg"],'error');
//            $this->_log("error = ".$_res["base_resp"]["err_msg"]);
            return false;
        }

        $redirect_url        =    $_res["redirect_url"];//跳转路径
        if(preg_match('/token=([\d]+)/i', $redirect_url,$match)){//获取cookie
            $this->setToken($match[1]);
        }
        echo "验证成功,token: ".$this->getToken();
        trace(date('Y-m-d H:i:s').'验证成功,token: '.$this->getToken(),'info');

        return $this->getToken();
    }




    //下载二维码
    private function _saveQRcode(){
        require_once VENDOR_PATH.'lib/QrReader.php';

        $_input["refer"] = $this->_redirect_url;
        $_res       = $this->fetch('qrcode',$_input);

        $_res = $_res->getBody()->getContents();

        $fp         = fopen($this->_getSavePath(), "wb+") or die("open fails");
        fwrite($fp,$_res) or die("fwrite fails");
        fclose($fp);
        
        $qrcode = new \QrReader($this->_getSavePath());  //图片路径
        $text = $qrcode->text(); //返回识别后的文本
        
        trace('二维码信息:'.$text,'info');

        $qrcode = \Shelwei\QRCode::terminal($text);
        echo $qrcode;

        return true;
    }




    //登陆
    private function _login(){
        $_input["post"] = array(
            'username' => $this->_username,
            'pwd' => md5($this->_password),
            'f' => 'json',
            'imgcode' => '',
            'ajax' => 1,
            'lang' => 'zh_CN',
            'userlang' => 'zh_CN',
            'token' => '',
        );
        $_input["refer"] = "https://mp.weixin.qq.com";
        $_res = $this->fetch('login', $_input);
        $_res = \GuzzleHttp\json_decode($_res->getBody()->getContents(),true);

        return $_res;  
    }






    private function getWxRandomNum(){
         return "0.".mt_rand(100000000, 999999999);
    }





    private function fetch($url_type,$_input){
        $headers = [
            'headers' => [
                'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
                'Accept-Encoding' => 'gzip, deflate, br',
                'Accept-Language' => 'zh-CN,zh;q=0.9',
                'Cache-Control' => 'max-age=0',
                'Host' => 'mp.weixin.qq.com',
                'User-Agent' => 'Mozilla/5.0 (Linux; U; Android 4.4.3; zh-cn; HTC 802w Build/KTU84L) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025489 Mobile Safari/533.1 MicroMessenger/6.3.13.49_r4080b63.740 NetType/WIFI Language/zh_CN',
                'Connection' => 'keep-alive'
            ],
            'verify'=>false
        ];

        if($url_type == 'host'){
            $jar = new CookieJar();
            $headers['cookies']=$jar;

            $url = $this->_apis[$url_type];
        }elseif($url_type == 'login'){
            $headers['headers']['Cookie']=file_get_contents($this->_getCookieFile());
            $jar = new CookieJar();
            $headers['cookies']=$jar;

            $url = $this->_apis[$url_type];
        }elseif ($url_type == 'bizlogin'){
            $headers['headers']['Cookie']=file_get_contents($this->_getCookieFile());
            $jar = new CookieJar();
            $headers['cookies']=$jar;

            $url = $this->_apis[$url_type];
        }else{
            $headers['headers']['Cookie']=file_get_contents($this->_getCookieFile());

            $url = $this->_apis[$url_type];
            if($url_type == 'qrcode'){
                $headers['headers']['Accept']='image/webp,image/apng,image/*,*/*;q=0.8';
            }
            if($url_type == 'loginask'){
                $url = $this->_apis[$url_type].$this->getWxRandomNum();
            }

        }



        if(isset($_input['post'])){
            $headers['form_params']=$_input['post'];
        }

        if(isset($_input['refer'])){
            $headers['headers']['Referer']=$_input['refer'];
        }

        $client = new Client();


        $response= $client->request(isset($_input['post'])?'POST':'GET',$url,$headers);



        if($response->getStatusCode() == 200){
            if(isset($jar)){
                $this->jar = $jar;
                $this->get_cookies($url_type);
            }
            return $response;
        }

    }




    private  function get_cookies(){
        $cookies_arr = $this->jar->toArray();
//        file_put_contents(RUNTIME_PATH.'wechat_gzh_cookie_jar.txt', serialize($this->jar));
        $cookies_str = '';

        foreach ($cookies_arr as $cookie) {
            redis()->hset($this->_key.'_cookie',$cookie['Name'],$cookie['Value'] );

            $cookies_str .= $cookie['Name'] . '=' . $cookie['Value'] . ';';
        }
        if (empty($cookies_str)) {
            echo 'no cookie';
            return false;
        }
        $new_cookies_str = substr($cookies_str, 0, -1);

        $fp = fopen($this->_getCookieFile(), "wb+") or die("open fails");
        fwrite($fp,$new_cookies_str) or die("fwrite fails");
        fclose($fp);

        return true;
    }



//    public function get_article_list(){
//        $param=[
//            'token'=>$this->getToken(),
//            'random'=>$this->getWxRandomNum(),
//            'query'=>'科技美学',
//            'begin'=>20,
//            'count'=>5
//        ];
//        $paramurl = http_build_query($param , '' , '&');
//        $httpurl = $this->_apis["searchbiz"].$paramurl ;
//
//        $_input['refer']='https://mp.weixin.qq.com/cgi-bin/appmsg?t=media/appmsg_edit_v2&action=edit&isNew=1&type=10&token=949583584&lang=zh_CN';
//        $res = $this->fetch($httpurl,$_input,"json");
//        return $res;
//    }



//    private function fetch($url, $_input = null, $data_type = 'json'){
//        $ch = curl_init();
//        $useragent = isset($_input['useragent']) ? $_input['useragent'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2';
//
//        curl_setopt($ch, CURLOPT_URL, $url);
//        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
//        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
//        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//        curl_setopt($ch, CURLOPT_POST, isset($_input['post']));
//
//        if (isset($_input['post'])) {
//            curl_setopt($ch, CURLOPT_POSTFIELDS, $_input['post']);
//        }
//
//        if (isset($_input['refer'])) {
//            curl_setopt($ch, CURLOPT_REFERER, $_input['refer']);
//        }
//
//        curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
//        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (isset($_input['timeout']) ? $_input['timeout'] : 5));
//        curl_setopt($ch, CURLOPT_COOKIEJAR, (isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile()));
//        curl_setopt($ch, CURLOPT_COOKIEFILE, (isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile()));
//        $result = curl_exec($ch);
//        curl_close($ch);
//
//
//        if ($data_type == 'json') {
//            $result = json_decode($result, true);
//        }
//
//        return $result;
//    }


}